home *** CD-ROM | disk | FTP | other *** search
/ QRZ! Ham Radio 8 / QRZ Ham Radio Callsign Database - Volume 8.iso / pc / files / sat / msat09.tgz / ALOGDISP.C < prev    next >
Text File  |  1994-09-17  |  19KB  |  695 lines

  1. /* program to display alog file
  2. ** Displays an ALyymmdd file.
  3. */
  4. /* Displays from FTL0 versions later than 13 March                                 */
  5. /* This program should be used for UO-14 AL files beginning with    */
  6. /* AL910403                                                                                                             */
  7. /*------------------------------------------------------------------------
  8.     JW Ward, G0/K8KA
  9.     HE Price, NK6k
  10.     15 April 1991
  11. ------------------------------------------------------------------------*/
  12.  
  13. #include <stdio.h>
  14. #include <string.h>
  15. #include <time.h>
  16. #include <stdlib.h>
  17.  
  18. #include "viewlog.h"
  19. #include "alog.h"
  20.  
  21. char buffer[40];
  22. struct ALOG_1F *alog_1f;
  23. struct ALOG_2F *alog_2f;
  24.  
  25. struct tm *utc;
  26.  
  27. struct CODE_MESSAGE
  28. {
  29.     int code;
  30.     char *message;
  31. };
  32.  
  33. /* PROTOTYPES */
  34. void pcallsession(void);
  35. void pcalla(void);
  36. void pcall(void);
  37. char *search_for_str(struct CODE_MESSAGE *code_array, int  code);
  38. char *short_time(long utc);
  39. int  get_alog_struct(FILE *fp, unsigned char *buffer);
  40. int  alog_struct_type(void);
  41.  
  42. /* CAUSES FOR FTL0 SESSION TERMINATION
  43. ** Used in calls to ftl_close_session()
  44. */
  45. #define    FTC_FRMR_REM    1                                                    /* Remote frame reject                 */
  46. #define    FTC_FRMR_LOCAL    2                                                /* Locally generated frmr            */
  47. #define    FTC_DISC_LOCAL    3                                                /* Locally requested disc            */
  48. #define    FTC_DISC_REM    4                                                    /* Remote requested disc            */
  49. #define    FTC_TIMEOUT    5                                                        /* AX25 timeout.                            */
  50. #define    FTC_RECONNECT    6                                                    /* Client reconnected.                */
  51. #define    FTC_QUIT    7                                                            /* BBS closed down.                        */
  52.  
  53. /* Reasons for closing an FTL0 session
  54. */
  55. struct CODE_MESSAGE close_reasons[] =
  56. {
  57.     {FTC_FRMR_REM,        "user FRMR"},
  58.     {FTC_FRMR_LOCAL,    "server FRMR"},
  59.     {FTC_DISC_LOCAL,    "server disconnect"},
  60.     {FTC_DISC_REM,        "user disconnect"},
  61.     {FTC_TIMEOUT,        "FTL0 timeout"},
  62.     {FTC_RECONNECT,        "reconnection"},
  63.     {FTC_QUIT,        "quit"},
  64.     {0,             "Undefined error"}
  65. };
  66.  
  67. struct CODE_MESSAGE disc_reasons[] =
  68. {
  69.     {DC_TIMEOUT,        "Inactivity timeout"},
  70.     {DC_IN_ULOK,        "Unexpected input (uplink command)"},
  71.     {DC_IN_DLOK,        "Unexpected input (downlink command)"},
  72.     {DC_IN_ULRX,        "Unexpected input (uplink data)"},
  73.     {DC_IN_DLEND,        "Unexpected input (downlink end)"},
  74.     {DC_UNKNOWN_PKT,    "FTL0 packet type unknown."},
  75.     {DC_PKT_TOO_BIG,    "FTL0 command packet too long."},
  76.     {0,             "Undefined error"}
  77. };
  78.  
  79. /* General FTL0 error messages
  80. */
  81.  
  82. struct CODE_MESSAGE ftl0_errors[]=
  83. {
  84.     {1,    "e:PG command bug"},
  85.     {2,    "e:cannot continue"},
  86.     {3,    "e:PACSAT err"},
  87.     {4,    "e:No such file"},
  88.     {5,    "e:Selection empty"},
  89.     {6,    "e:Mandatory PFH err"},
  90.     {7,    "e:PHF err"},
  91.     {8,    "e:Bad selection"},
  92.     {9,    "e:File locked"},
  93.     {10,    "e:No such destination"},
  94.     {11,    "e:File partial."},
  95.     {12,    "e:File complete."},
  96.     {13,    "e:PACSAT file system full"},
  97.     {14,    "e:PFH err"},
  98.     {15,    "e:PFH checksum failure"},
  99.     {16,    "e:body checksum failure"},
  100.     {0,    ""}
  101. };
  102.  
  103. /* Events logged in the ALOG, in numerical order of their event code,
  104. ** beginning with event 0 (nothing).
  105. */
  106.  
  107. char *event_text[] =
  108. {
  109.     " ",
  110.     "STARTUP",
  111.     "SHUTDOWN",
  112.     "LOGIN",
  113.     "LOGOUT",
  114.     "BLOWOFF",
  115.     "REFUSED",
  116.     "BCST ON",
  117.     "BCST OFF",
  118.     "FREE DISK",
  119.     "DELETE",
  120.     "DOWNLOAD",
  121.     "UPLOAD",
  122.     "SHUT",
  123.     "OPEN",
  124.     "DIR",
  125.     "SELECT",
  126.     "ADEL OK",
  127.     "ADEL FAIL",
  128.     "DL DONE",
  129.     "UL DONE",
  130.     "DIR DONE",
  131.     "SEL DONE",
  132. };
  133.  
  134. #define MAX_SESSION 20
  135.  
  136. /* keep last MAX_SESSION sessions, for printing callsign */
  137.  
  138. struct
  139. {
  140.     unsigned char  call[6];
  141.     unsigned char  ssid;
  142.     unsigned short session;
  143. }
  144. session[MAX_SESSION];
  145.  
  146. char writebuf[200];
  147.  
  148. int sidx = 0;
  149.  
  150. #define msmin  (long) (60l)
  151. #define mshour (long) (60l * 60l)
  152. #define msday  (long) (60l * 60l *24l)
  153.  
  154. int alogdisp(FILE *fp)
  155. {
  156.     int first = 1;
  157.     char *err_str;
  158.     int err;
  159.     int day, hour, min, sec;
  160.     long tmpl;
  161.     char tmptxt1[25];
  162.  
  163.     /* Effectively unions with the input buffer */
  164.     alog_1f = (struct ALOG_1F *)buffer;
  165.     alog_2f = (struct ALOG_2F *)buffer;
  166.  
  167.     while (1)
  168.     {
  169.         err = get_alog_struct(fp, buffer);
  170.  
  171.         if (err != 0)
  172.         {
  173.             fclose(fp);
  174.             return(err - 1);
  175.         }
  176.         
  177.         /* Print the header once per log file */
  178.         if (first)
  179.         {
  180.             sprintf(writebuf, "FTL0 Activity Log for %s", asctime(gmtime(&alog_1f->tstamp)));
  181.             writetext(writebuf);
  182.             sprintf(writebuf, "\nTime      Activity   Call      Rx Session\n");
  183.             writetext(writebuf);
  184.             first = 0;
  185.         }
  186.  
  187.         if (alog_1f->var3 != 0L)
  188.             err_str = search_for_str(ftl0_errors, (int)alog_1f->var3);
  189.         else
  190.             err_str = "";
  191.  
  192.         switch (alog_1f->event)
  193.         {
  194.         case ALOG_FTL0_STARTUP:
  195.             /* FTL0 BBS code executed */
  196.             sprintf(writebuf, "%s  %-9.9s  ", short_time(alog_1f->tstamp), event_text[alog_1f->event]);
  197.             writetext(writebuf);
  198.             break;
  199.  
  200.         case ALOG_FTL0_SHUTDOWN:
  201.             /* FTL0 BBS task exits. */
  202.             sprintf(writebuf, "%s  %-9.9s  ", short_time(alog_1f->tstamp), event_text[alog_1f->event]);
  203.             writetext(writebuf);
  204.             break;
  205.         
  206.         case ALOG_BBS_SHUT:
  207.             /* Ground command shuts bbs */
  208.             pcalla();
  209.             break;
  210.  
  211.         case ALOG_BBS_OPEN:
  212.             /* Ground command opens bbs */
  213.             pcalla();
  214.             break;
  215.  
  216.         case ALOG_BCAST_START:
  217.             /* User starts a broadcast
  218.                  var1 = file number
  219.                  var2 = number of seconds for broadcast
  220.                  var3 = error
  221.                  var4 = length of data packets
  222.             */
  223.             pcalla();
  224.             if (alog_2f->var3 != 0L)
  225.                 err_str = search_for_str(ftl0_errors, (int)alog_2f->var3);
  226.             else
  227.                 err_str = "";
  228.  
  229.             sprintf(writebuf, "        f#%lx dur:%lu l:%ld %s", alog_2f->var1,
  230.                 alog_2f->var2,alog_2f->var4,err_str);
  231.             writetext(writebuf);
  232.             break;
  233.  
  234.         case ALOG_BCAST_STOP:
  235.             /* User stops a broadcast
  236.                  var1 = file number
  237.                  var2 = unused
  238.                  var3 = error
  239.             */
  240.             pcalla();
  241.             if (alog_2f->var3 != 0L)
  242.                 err_str = search_for_str(ftl0_errors, (int)alog_2f->var3);
  243.             else
  244.                 err_str = "";
  245.             sprintf(writebuf, "        f#%lx  %s", alog_2f->var1, err_str);
  246.             writetext(writebuf);
  247.             break;
  248.  
  249.         case ALOG_DISKSPACE:
  250.             /* Diskspace is logged hourly
  251.                  var1 = number of disk clusters free (1008 bytes of data each)
  252.                  var2 = number of directory entries free
  253.             */
  254.             sprintf(writebuf, "%s  %-9.9s  ", short_time(alog_1f->tstamp), event_text[alog_1f->event]);
  255.             writetext(writebuf);
  256.             sprintf(writebuf, "                     %ld bytes \\", alog_1f->var1 * 1008l);
  257.             writetext(writebuf);
  258.             sprintf(writebuf, " %ld dirs", alog_1f->var2);
  259.             writetext(writebuf);
  260.             break;
  261.  
  262.         case ALOG_FILE_DELETE:
  263.             /* Command station deletes file
  264.                  var1 = file number
  265.                  var2 = unused
  266.                  var3 = error code
  267.             */
  268.             pcalla();
  269.             if (alog_1f->var3 != 0L)
  270.                 err_str = search_for_str(ftl0_errors, (int)alog_1f->var3);
  271.             else
  272.                 err_str = "";
  273.             sprintf(writebuf, "        f#%lx", alog_1f->var1);
  274.             writetext(writebuf);
  275.             break;
  276.  
  277.         case ALOG_USER_REFUSED:
  278.             sprintf(writebuf, "%s  %-9.9s  ",short_time(alog_1f->tstamp), event_text[alog_1f->event]);
  279.             writetext(writebuf);
  280.             /* BBS was full.
  281.             */
  282.             break;
  283.  
  284.         case ALOG_START_SESSION:
  285.             /* User logs on. This is the only time we get callsign
  286.                  information for connected mode users; must use serial_no
  287.                  from now on.
  288.             */
  289.             pcallsession();
  290.             sprintf(writebuf, " %06u", alog_1f->serial_no);
  291.             writetext(writebuf);
  292.             break;
  293.  
  294.         case ALOG_CLOSE_SESSION:
  295.             /* Server closes session.
  296.                 var1 = reason for closing session, see close_reasons array.
  297.                 var2 = bytes downloaded, if download in progress
  298.                 var3 = bytes uploaded, if upload in progress
  299.                 var2 and var3 are 0 if no transfer in progress.
  300.                 download includes directory commands.
  301.             */
  302.             pcall();
  303.             sprintf(writebuf, " %06u", alog_1f->serial_no);
  304.             writetext(writebuf);
  305.             sprintf(writebuf, " %s  ", search_for_str(close_reasons, (int)alog_1f->var1));
  306.             writetext(writebuf);
  307.             if (alog_1f->var2)
  308.             {
  309.                 sprintf(writebuf, "\n%41.41s Incomplete D/L @ %lu bytes", "", alog_1f->var2);
  310.                 writetext(writebuf);
  311.             }
  312.             if (alog_1f->var3)
  313.             {
  314.                 sprintf(writebuf, "\n%41.41s Incomplete U/L @ %lu bytes", "", alog_1f->var3);
  315.                 writetext(writebuf);
  316.             }
  317.             break;
  318.  
  319.         case ALOG_DISCONNECT :
  320.             /* Server is disconnecting user.
  321.                  var1 = reason for disconnect, see disc_reasons array.
  322.             */
  323.             pcall();
  324.             sprintf(writebuf, " %s  ", search_for_str(disc_reasons, (int)alog_1f->var1));
  325.             writetext(writebuf);
  326.             break;
  327.         
  328.         case ALOG_FILE_DOWNLOAD:
  329.             /* Server receives download command.
  330.                  var1 = file number
  331.                  var2 = continue offset
  332.                  var3 = error code
  333.                  var4 = flag indicating that download was from select list.
  334.             */
  335.             pcall();
  336.             if (alog_1f->var3 != 0L)
  337.                 err_str = search_for_str(ftl0_errors, (int)alog_1f->var3);
  338.             else
  339.                 err_str = "";
  340.             sprintf(writebuf, "        f#%lx off:%lu %s",alog_1f->var1,
  341.                 alog_1f->var2, err_str);
  342.             writetext(writebuf);
  343.             if (alog_1f->var4)
  344.                 writetext("(selected)");
  345.             break;
  346.  
  347.         case ALOG_END_DOWNLOAD:
  348.             /* User has indicated end of download to server. May be good or bad.
  349.                  var1 = number of bytes downloaded. Not necessarily file length,
  350.                         if this was a continued download.
  351.                  var2 = FTL_DL_ACK_CMD if user acked.
  352.                         FTL_DL_NAK_CMD if user n'acked.
  353.                  User may n'ack if checksum fails.
  354.             */
  355.             pcall();
  356.             sprintf(writebuf, "        %ld bytes ", alog_1f->var1);
  357.             writetext(writebuf);
  358.             if ((unsigned char)alog_1f->var2 == 0x0c)
  359.                 writetext("Ack'd");
  360.             else
  361.                 writetext("Nak'd");
  362.             break;
  363.  
  364.         case ALOG_FILE_UPLOAD:
  365.             /* Server receives client's upload command.
  366.                  var1 = file number
  367.                  var2 = continue offset
  368.                  var3 = error code
  369.                  var4 = file length as told by client to server.
  370.             */
  371.             pcall();
  372.             if (alog_1f->var3 != 0L)
  373.                 err_str = search_for_str(ftl0_errors, (int)alog_1f->var3);
  374.             else
  375.                 err_str = "";
  376.             sprintf(writebuf, "        f#%lx off:%lu l#%lu %s", alog_1f->var1,
  377.                 alog_1f->var2,alog_1f->var4, err_str);
  378.             writetext(writebuf);
  379.             break;
  380.  
  381.         case ALOG_END_UPLOAD:
  382.             /* Server has received, and finished checksumming, the file.
  383.                  var1 = time checksum started. Subtractr from alog_1f->time
  384.                         to figure out how many seconds to checksum the file.
  385.                  var2 = error code.
  386.                  var3 = number of bytes uploaded; not necessarily same as file size,
  387.                         since this might be a continued upload.
  388.             */
  389.             pcall();
  390.             sprintf(writebuf, "        %ld bytes %ld seconds cksum", alog_1f->var3,
  391.                 alog_1f->tstamp - alog_1f->var1);
  392.             writetext(writebuf);
  393.             if (alog_1f->var2)
  394.                 writetext(" Nak'd");
  395.             break;
  396.  
  397.         case ALOG_DIR:
  398.             /* Server receives directory request from client.
  399.                  var1 = file number (0xffffffff or 0 indicate dir from selection.)
  400.                  var2 = error code.
  401.             */
  402.             pcall();
  403.             if (alog_1f->var2 != 0L)
  404.                 err_str = search_for_str(ftl0_errors, (int)alog_1f->var2);
  405.             else
  406.                 err_str = "";
  407.             if (alog_1f->var1 != 0xffffffff && alog_1f->var1 != 0L)
  408.                 sprintf(writebuf, "        f#%lx  %s", alog_1f->var1, err_str);
  409.             else
  410.                 sprintf(writebuf, "        from selection.");
  411.             writetext(writebuf);
  412.             break;
  413.  
  414.         case ALOG_END_DIR:
  415.             /* Server sends last packet of directory to client.
  416.                  var1 = total number of bytes in directory.
  417.               */
  418.                 pcall();
  419.                 sprintf(writebuf, "        %ld bytes", alog_1f->var1);
  420.                 writetext(writebuf);
  421.                 break;
  422.  
  423.             /* Automatic file removal
  424.                  var1 = file number
  425.                  var2 = free directory entries in system
  426.                  var3 = free file clusters in system
  427.                  var4 = expiry time (earliest at which file could be deleted)
  428.             */
  429.         case ALOG_FILE_REMOVED:
  430.             sprintf(writebuf, "%s  %-9.9s  ",short_time(alog_1f->tstamp), event_text[alog_1f->event]);
  431.             writetext(writebuf);
  432.             sprintf(writebuf, "        f#%lx (exp: (%lx) %24.24s)",alog_1f->var1,alog_1f->var4,
  433.                 asctime(gmtime(&(alog_1f->var4))));
  434.             writetext(writebuf);
  435.             break;
  436.  
  437.         case ALOG_FILE_NOT_REMOVED:
  438.             sprintf(writebuf, "%s  %-9.9s  ", short_time(alog_1f->tstamp), event_text[alog_1f->event]);
  439.             writetext(writebuf);
  440.             sprintf(writebuf, "        f#%lx (exp: (%lx) %24.24s)", alog_1f->var1,alog_1f->var4,
  441.                 asctime(gmtime(&(alog_1f->var4))));
  442.             writetext(writebuf);
  443.             break;
  444.  
  445.         case ALOG_SELECT:
  446.         /* Select command received by server. No vars used */
  447.             pcall();
  448.             break;
  449.  
  450.         case ALOG_SELECT_DONE:
  451.         /* Finished building select list
  452.              var1 = length of user's selection equation
  453.              var2 = oldest file considered for the selection
  454.              var3 = newest file considered for the selection
  455.              var4 = number of files selected
  456.         */
  457.             pcall();
  458.             if (alog_1f->var2 == 0x131d1741) 
  459.                 strcpy(tmptxt1, "start");
  460.             else
  461.             {
  462.                 /* compute time before "now" */
  463.                 tmpl = alog_1f->tstamp - alog_1f->var2;
  464.                 if (tmpl < 0)
  465.                     strcpy(tmptxt1, "future?");
  466.                 else
  467.                 {
  468.                     day = tmpl / msday;
  469.                     tmpl= tmpl % msday;
  470.                     hour = tmpl / mshour;
  471.                     tmpl = tmpl % mshour;
  472.                     min = tmpl / msmin;
  473.                     tmpl = tmpl % msmin;
  474.                     sec = tmpl;
  475.                     sprintf(tmptxt1,"%03u/%02u:%02u:%02u",
  476.                         day, hour, min, sec);
  477.                 }
  478.             }
  479.             sprintf(writebuf, "        %s len:%ld selected:%ld",
  480.                 tmptxt1, alog_1f->var1, alog_1f->var4);
  481.             writetext(writebuf);
  482.             break;
  483.  
  484.         default:
  485.             sprintf(writebuf, "%s  %-9.9s  ", short_time(alog_1f->tstamp), event_text[alog_1f->event]);
  486.             writetext(writebuf);
  487.             sprintf(writebuf, "Unknown (%d)", alog_1f->event);
  488.             writetext(writebuf);
  489.             break;
  490.         }
  491.  
  492.         writetext("\n");
  493.     }
  494.  
  495.     return(0);
  496. }
  497.  
  498. /*------------------------------------------------------------------------
  499.  Prints callsign for the beginning of a session, and puts the
  500.  call and ssid into the structure array holding each session.
  501. ------------------------------------------------------------------------*/
  502.  
  503. void pcallsession(void)
  504. {
  505.     memcpy(session[sidx].call, alog_2f->call, 6);
  506.     session[sidx].ssid = alog_2f->ssid;
  507.     session[sidx].ssid = alog_2f->ssid;
  508.     session[sidx].session = alog_2f->serial_no;
  509.  
  510.     /* Move circularly through session array. */
  511.     sidx = (sidx + 1) % MAX_SESSION;
  512.  
  513.     sprintf(writebuf, "%s  %-9.9s  ", short_time(alog_1f->tstamp), event_text[alog_1f->event]);
  514.     writetext(writebuf);
  515.     sprintf(writebuf, "%6.6s-%-2u  %u ", alog_2f->call,alog_2f->ssid, alog_2f->rxchan);
  516.     writetext(writebuf);
  517. }
  518.  
  519. /*------------------------------------------------------------------------
  520.   Prints callsign for action not related to a connected session.
  521.     Takes call, ssid and receiver out of current alog_2f structure.
  522. ------------------------------------------------------------------------*/
  523.  
  524. void pcalla(void)
  525. {
  526.     sprintf(writebuf, "%s  %-9.9s  ", short_time(alog_1f->tstamp), event_text[alog_1f->event]);
  527.     writetext(writebuf);
  528.     sprintf(writebuf, "%6.6s-%-2u  %u ", alog_2f->call,alog_2f->ssid, alog_2f->rxchan); 
  529.     writetext(writebuf);
  530. }
  531.  
  532. /*------------------------------------------------------------------------
  533.   Prints callsign for action within a connected session.
  534.     Looks up correct session in session[] using serial_no from current
  535.     alog_1f structure.
  536.     Takes call and ssid out of session[].
  537. ------------------------------------------------------------------------*/
  538.  
  539. void pcall(void)
  540. {
  541.     int i;
  542.     /* Find the session looking up serial numbers */
  543.  
  544.     for (i = 0; i < MAX_SESSION; i++)
  545.         if (session[i].session == alog_1f->serial_no)
  546.             break;
  547.  
  548.     /* Found it */
  549.     sprintf(writebuf, "%s  %-9.9s  ",short_time(alog_1f->tstamp), event_text[alog_1f->event]);
  550.     writetext(writebuf);
  551.  
  552.     if (i < MAX_SESSION) 
  553.     {
  554.         sprintf(writebuf, "%6.6s-%-2u    ", session[i].call, session[i].ssid);
  555.         writetext(writebuf);
  556.     }
  557.     else
  558.     {
  559.         writetext("******-**    "); 
  560.     }
  561. }
  562.  
  563. char *search_for_str(struct CODE_MESSAGE code_array[], int code)
  564. {
  565.     int i = 0;
  566.  
  567.     if (code == -1) return("Can't add");
  568.  
  569.     while (code_array[i].code != code && code_array[i].code != 0)
  570.         ++i;
  571.  
  572.     return(code_array[i].message);
  573. }
  574.  
  575. /*------------------------------------------------------------------------
  576.     provide an HH:MM:SS timestamp.
  577. ------------------------------------------------------------------------*/
  578.  
  579. char time_stamp[9];
  580.  
  581. char *short_time(time_t utc)
  582. {
  583.     struct tm *tp;
  584.  
  585.     tp = gmtime(&utc);
  586.  
  587.     sprintf(time_stamp, "%02d:%02d:%02d", tp->tm_hour, tp->tm_min, tp->tm_sec);
  588.  
  589.     return time_stamp;
  590. }
  591.     
  592.  
  593. /*------------------------------------------------------------------------
  594.     Read a variable length record from the file.
  595.     The first byte is always record type.
  596.     The second byte is always record length.
  597.     See alog.h for further details of the two variable length structs
  598.     which can be in the file.
  599. ------------------------------------------------------------------------*/
  600.  
  601. int get_alog_struct(FILE *fp, unsigned char *buffer)
  602. {
  603.     int cnt;
  604.     int error = 0;
  605.  
  606.     /* First two bytes contain structure length */
  607.     cnt = fread(buffer, 1, 2, fp);
  608.  
  609.     if (cnt != 2)
  610.     {
  611.         error = 1;
  612.     }
  613.     /* Alog structure never greater then 40 bytes */
  614.     else if (alog_1f->len > 40)
  615.     {
  616.         error = 2;
  617.     }
  618.     else
  619.     {
  620.         /* Get the rest of the structure, now length is known */
  621.         cnt = fread(buffer+2, 1, alog_1f->len-2, fp);
  622.  
  623.         if (cnt + 2 != alog_1f->len)
  624.         {
  625.             error = 3;
  626.         }
  627.     }
  628.  
  629.     return error;
  630. }
  631.  
  632. /*------------------------------------------------------------------------
  633.     Checks the type of record in the global alog structure and returns
  634.     an appropriate integer. Generally, this tells if the record type is
  635.     alog1 or alog2, though some other divisions have been introduced.
  636.     
  637.     START_SESSION MUST RETURN 2
  638.     CONNECTED MODE OPERATIONS MUST RETURN 1
  639.     ADMINISTRATIVE OPERATIONS MUST RETURN 0
  640. ------------------------------------------------------------------------*/
  641.  
  642. int alog_struct_type(void)
  643. {
  644.     int type;
  645.  
  646.     switch (alog_1f->event)
  647.     {
  648.         /* All of these have callsigns in them */
  649.         case ALOG_START_SESSION:
  650.         case ALOG_BCAST_START:
  651.         case ALOG_BCAST_STOP:
  652.         case ALOG_FILE_DELETE:
  653.         case ALOG_BBS_SHUT:
  654.         case ALOG_BBS_OPEN:
  655.             type = 2;
  656.             break;
  657.  
  658.         /* These don't have or refer to callsigns. This is the */
  659.         /* group containing all automatic s/c generated events.*/
  660.         case ALOG_FTL0_STARTUP:
  661.         case ALOG_FTL0_SHUTDOWN:
  662.         case ALOG_DISKSPACE:
  663.         case ALOG_FILE_REMOVED:
  664.         case ALOG_FILE_NOT_REMOVED:
  665.             type = 0;
  666.             break;
  667.  
  668.         /* All connected mode events */
  669.         case ALOG_CLOSE_SESSION:
  670.         case ALOG_DISCONNECT:
  671.         case ALOG_FILE_DOWNLOAD:
  672.         case ALOG_FILE_UPLOAD:
  673.         case ALOG_DIR:
  674.         case ALOG_SELECT:
  675.         case ALOG_END_DOWNLOAD:
  676.         case ALOG_END_UPLOAD:
  677.         case ALOG_END_DIR:
  678.         case ALOG_SELECT_DONE:
  679.             type = 1;
  680.             break;
  681.  
  682.         /* Put refusals in a class by themselves, because they are anoying */
  683.         case ALOG_USER_REFUSED:
  684.             type = 4;
  685.             break;
  686.  
  687.         default:
  688.             type = 3;
  689.             break;
  690.     }
  691.  
  692.     return type;
  693. }
  694.  
  695.